home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Sample Code / Devices / ATA demo 1.1 / ATA Demo.c < prev    next >
Encoding:
Text File  |  1997-11-07  |  19.5 KB  |  649 lines  |  [TEXT/CWIE]

  1. /*/*************************************************************************
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    Macintosh ATA Manager Sample 
  5. **
  6. **    by Vinne Moscaritolo, <vinnie@apple.com>
  7. **    Apple Developer Technical Support 
  8. **
  9. **  Created from as much sample code I could find.
  10. **  with much help from Gary Wilkinson, Rich Schnell and  Martin Minow
  11. **
  12. **  " Good Artists Imitate, Great Artist Steal "
  13. **
  14. **    File:        ATA Demo.c
  15. **
  16. **    Copyright © 1996, 1997 Apple Computer, Inc.
  17. **    All rights reserved.
  18. **
  19. **    Modifications:
  20. **        971005    BLoB    Buffer was incorrect size in 
  21. **                        DisplayATADriveIdentity routine.
  22. **                        Modified to CW Pro 1 and its headers
  23. **                        Added Metrowerks SIOUX specific stuff
  24. **                        Created Fat application
  25. **                        Realized that the words come back swapped; 
  26. **                        adjusted for this in the DumpFormatedBuffer routine.
  27. **
  28. **    You may incorporate this sample code into your applications without
  29. **    restriction, though the sample code has been provided "AS IS" and the
  30. **    responsibility for its operation is 100% yours.  However, what you are
  31. **    not permitted to do is to redistribute the source as "DSC Sample Code"
  32. **    after having made changes. If you're going to re-distribute the source,
  33. **    we require that you make it clear in the source that the code was
  34. **    descended from Apple Sample Code, but that you've made changes.
  35. **
  36. **************************************************************************/
  37.  
  38.  
  39.  
  40. //------------------------------------------------------------------------------------
  41. #pragma mark Includes
  42. //------------------------------------------------------------------------------------
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <ATA.h>
  46. #ifdef __MWERKS__
  47.     #include <SIOUX.h>
  48. #endif
  49. #include "ata_powerpc.h"
  50. //------------------------------------------------------------------------------------
  51. #pragma mark Defines
  52. //------------------------------------------------------------------------------------
  53.  
  54. //
  55. // Identifies the bus protocol type.
  56. //
  57.  
  58. enum {
  59.     kDevUnknown        =    0,
  60.     kDevATA            =    1,
  61.     kDevATAPI        =    2,
  62.     kDevPCMCIA        =    3
  63. };
  64.  
  65. //
  66. // Identifies the Socket type.
  67. //
  68. enum {
  69.     kSocketUnknown        =    0,
  70.     kSocketInternal        =    1,
  71.     kSocketMediaBay        =    2,
  72.     kkSocketPCMCIA        =    3
  73. };
  74.  
  75. //------------------------------------------------------------------------------------
  76. #pragma mark Macros
  77. //------------------------------------------------------------------------------------
  78.  
  79. #define CLEAR(what) do {                        \
  80.         register Ptr        _ptr = (Ptr) &what;    \
  81.         register Size        _len = sizeof what;    \
  82.         for (; _len > 0; --_len)                    \
  83.             *_ptr++ = 0;                        \
  84.     } while (0)
  85.  
  86. #define IF_ERROR(_err_,_str_) if (_err_ != noErr) { printf(_str_); return (_err_); }
  87.  
  88.  
  89. //------------------------------------------------------------------------------------
  90. #pragma mark -
  91.  
  92. //------------------------------------------------------------------------------------
  93. #pragma mark Identify Drive Info
  94. //------------------------------------------------------------------------------------
  95.  
  96. //
  97. //  Bit fields returned from Identify Drive command
  98. //
  99. enum {
  100.     magdrv_bit        =    15,            /* WORD 0: bit number of mag drive indicator    */
  101.     rcd_bit            =    7,            /* WORD 0: bit number of removable indicator    */
  102.     fixed_bit        =    6,            /* WORD 0: bit number of fixed disk indicator    */
  103.  
  104.     lbamode_bit        =    9,            /* bit number of lba support indicator            */
  105.     iordy_bit        =    11,            /* bit number of IORDY support indicator        */
  106.     extvalid_bit    =    1,            /* bit number of valid extension word            */
  107.     mode3_bit        =    0,            /* WORD 64: bit number of mode 3 support        */
  108.     
  109.     kMagDrv            =    1 << magdrv_bit,    /* Bit 15 = 0 -> a magnetic drive        */
  110.     kRemovable        =    1 << rcd_bit,        /* Bit 7 != 0 -> removable cartridge    */
  111.     kFixed            =    1 << fixed_bit,        /* Bit 6 != 0 -> indicates fixed drive    */
  112.     kLBAMode        =    1 << lbamode_bit,    /* LBA support indicator                */
  113.     kIORDY            =    1 << iordy_bit,        /* IORDY support indicator                */
  114.     kExtValid        =    1 << extvalid_bit,    /* Extension word valid                    */
  115.     MODE3BIT        =    1 << mode3_bit        /* mode 3 bit in word 64 of ident data    */
  116. };
  117.  
  118. //
  119. // This is returned by the device in response to an IDENTIFY command (512 bytes).
  120. //
  121. typedef    struct IdentifyBlock {    /* Structure of Identify data                        */
  122.     short    Signature;            /* Word 00: Constant value                            */
  123.     short    NumCyls;            /* Word 01:    Number of cylinders (default mode)            */
  124.     short    RSVD0;                /* Word 02:    Constant value of 0                        */
  125.     short    NumHds;                /* Word 03:    Number of heads (default mode)            */
  126.     short    TrkBytes;            /* Word 04:    Number of unformatted bytes/track        */
  127.     short    SecBytes;            /* Word 05:    Number of unformatted bytes/sector        */
  128.     short    NumSecs;            /* Word 06:    Number of sectors/track                    */
  129.     short    VU0;                /* Word 07:    Vendor unique                            */
  130.     short    VU1;                /* Word 08:    Vendor unique                            */
  131.     short    VU2;                /* Word 09:    Vendor unique                            */
  132.     short    Serial[10];            /* Word 10-19:    Serial Number (right-justified)        */
  133.     short    BufType;            /* Word 20:    Buffer Type                                */
  134.     short    BufSize;            /* Word 21:    Buffer size in 512 byte increments        */
  135.     short    NumECC;                /* Word 22:    Number of ECC bytes                        */
  136.     short    FirmRev[4];            /* Word 23-26:    Firmware revision (left-justified)    */
  137.     short    ModelNum[20];        /* Word 27-46:    Model number (left-justified)        */
  138.     short    MultCmds;            /* Word 47:    R/W multiple commands not impl = 0        */
  139.     short    DblXferFlag;        /* Word 48:    Double transfer flag                    */
  140.     short    Capabilities;        /* Word 49: LBA, DMA, IORDY support indicator        */
  141.     short    Reserved1;            /* Word 50: Reserved                                */
  142.     short    PIOTiming;            /* Word 51: PIO transfer timing mode                */
  143.     short    DMATiming;            /* Word 52:    DMA transfer timing mode                */
  144.     short    Extension;            /* Word 53: extended info support                    */
  145.     short    CurCylinders;        /* Word 54: number of current cylinders                */
  146.     short    CurHeads;            /* Word 55: number of current heads                    */
  147.     short    CurSPT;                /* Word 56: number of current sectors per track        */
  148.     short    CurCapacity[2];        /* Word 57-58: current capacity in sectors            */
  149.     short    MultSectors;        /* Word 59: Multiple sector setting                    */
  150.     short    LBACapacity[2];        /* Word 60-61: total sectors in LBA mode            */
  151.     short    SWDMA;                /* Word 62: single word DMA support                    */
  152.     short    MWDMA;                /* Word 63: multi word DMA support                    */
  153.     short    APIOModes;            /* Word 64:    Advanced PIO Xfr mode supported            */
  154.     short    MDMATiming;            /* Word 65:    Minimum Multiword DMA Xfr Cycle            */
  155.     short    RDMATiming;            /* Word 66:    Recommended Multiword DMA Cycle            */
  156.     short    MPIOTiming;            /* Word 67:    Min PIO XFR Time W/O Flow Control        */
  157.     short    PIOwRDYTiming;        /* Word 68:    Min PIO XFR Time with IORDY flow ctrl    */
  158.     short    Reserved[187];        /* Word 69-255: Reserved                            */
  159. } IdentifyBlock;
  160.  
  161. //
  162. // The following structure and table simplifies the formatting.
  163. //
  164. enum {
  165.     kEndOfTable = 0,            /* Marker                                            */
  166.     kDecimal,                    /* Signed integer (two words are high..low)            */
  167.     kHex,                        /* Bitfield                                            */
  168.     kLeftJust,                    /* Ascii, left-justified, space padded                */
  169.     kRightJust                    /* Ascii, right-justified, space padded                */
  170. };
  171. struct FormatTable {
  172.     short        firstWord;        /* First word in IdentifyBlock cast to short vector    */
  173.     short        lastWord;        /* Last word in IdentifyBlock cast to short vector    */
  174.     short        format;            /* Format from above enum                            */
  175.     const char    *label;            /* Text to display                                    */
  176. };
  177.  
  178. typedef struct FormatTable FormatTable, *FormatTablePtr;
  179.  
  180. FormatTable kIdentFormat[] = {
  181.     {     0,     0, kHex,        "Configuration word"                        },
  182.     {     1,     1,    kDecimal,    "Cylinders"            },
  183.     {     3,     3,    kDecimal,    "Heads"                },
  184.     {     4,     4,    kDecimal,    "Bytes/Track"            },
  185.     {     5,     5,    kDecimal,    "Bytes/Sector (0 = 512 bytes)"        },
  186.     {     5,     5,    kDecimal,    "Sectors/Track"        },    /* 35 */
  187.     {     7,     9,    kHex,        "Vendor Unique (word 7..9)"                    },
  188.     {    10,    19,    kRightJust,    "Serial Number"                                },
  189.     {    20,    20,    kHex,        "Buffer Type"                                },
  190.     {    21,    21,    kDecimal,    "Buffer size in 512 byte increments"        },
  191.     {    22,    22,    kDecimal,    "Number of ECC bytes available"                },
  192.     {    23,    26,    kLeftJust,    "Firmware Revision"                            },
  193.     {    27,    46,    kLeftJust,    "Model Number"                                },
  194.     {    47,    53,    kHex,        "Capability Flags (word 47..53)"            },
  195.     {    54,    54,    kDecimal,    "Cylinders (current mode)"        },
  196.     {    55,    55,    kDecimal,    "Heads (current mode)"            },
  197.     {    56,    56,    kDecimal,    "Sectors/Track (current mode)"        },
  198.     {    57,    58,    kDecimal,    "Current Capacity in Sectors"                },
  199.     {    59,    59,    kHex,        "Multiple Sector Capability Flag"            },
  200.     {    60,    61,    kDecimal,    "Current User-addressable Sectors"            },
  201.     {    62,    62,    kHex,        "Single Word DMA Transfer Mode Flags"        },
  202.     {    63,    63,    kHex,        "Multiword DMT Transfer Mode Flags"            },
  203.     {     0,  0,    kEndOfTable,""                                            }
  204. };
  205.  
  206.  
  207.  
  208. //------------------------------------------------------------------------------------
  209. #pragma mark Prototypes
  210. //------------------------------------------------------------------------------------
  211.  
  212. Boolean     ATAManagerPresent    (void);
  213. Boolean     ATAHardwarePresent    (void);
  214. Boolean     TrapAvailable        (short theTrap);
  215. void         PrintNumVersion        (char *label, NumVersion version );
  216. OSErr         DisplayATAManagerInquiryInfo (void);
  217.  
  218. OSErr         ScanATABusses         (void);
  219. OSErr         DisplayATADriveIdentity (UInt32 deviceID );
  220. void        DumpRawBuffer        ( UInt8 *bufferPtr, int length );
  221. void        DumpFormatedBuffer    (void* p, const  FormatTablePtr formatPtr);
  222. char*        DrvrRefToName        (short refNum);
  223.  
  224.  
  225.  
  226. //------------------------------------------------------------------------------------
  227. #pragma mark -
  228.  
  229.  
  230. // ---------------------------------------------------------------------------
  231. void     main     (void)
  232. // ---------------------------------------------------------------------------
  233. {
  234.     OSErr            status;
  235.  
  236. #ifdef __MWERKS__
  237.     SIOUXSettings.asktosaveonclose = false;
  238. #endif
  239.  
  240.     printf("Macintosh ATA Manager Sample\n\n");
  241.  
  242. // Check for ATA Hardware 
  243. // you should do this before calling the ATAManager, since some early ROMS
  244. // could indicate an ATA manager without the proper HW, thus casing a crash.
  245.     if (ATAHardwarePresent() == FALSE) {
  246.         printf("ATA Hardware is not present on this system\n");
  247.         exit(EXIT_FAILURE);
  248.     }
  249.  
  250. // Check for ATA Manager
  251.     if (ATAManagerPresent() == FALSE) {
  252.         printf("ATA Manager is not present on this system\n");
  253.         exit(EXIT_FAILURE);
  254.     }
  255.         
  256. // Display ATA Manager Info
  257.     status = DisplayATAManagerInquiryInfo();
  258.     if (status != noErr) {
  259.         printf("Cannot access ATA Manager: %d\n", (int) status);
  260.         exit(EXIT_FAILURE);
  261.     }
  262.     
  263. // Display ATA Device Info
  264.     status = ScanATABusses();
  265.     if (status != noErr) {
  266.         printf("Cannot access ATA Manager: %d\n", (int) status);
  267.         exit(EXIT_FAILURE);
  268.     }
  269. }
  270.  
  271.  
  272. // ---------------------------------------------------------------------------
  273. OSErr         DisplayATAManagerInquiryInfo (void)
  274. // ---------------------------------------------------------------------------
  275. //
  276. //  Display information about the ATA Manager
  277. //
  278. {
  279.     ataMgrInquiry    pb;
  280.     OSErr            status;
  281.  
  282.     CLEAR(pb);
  283.     
  284.     pb.ataPBFunctionCode =    kATAMgrManagerInquiry;
  285.     pb.ataPBVers =            kATAPBVers1;
  286.  
  287.     status = ataManager((ataPB*) &pb );
  288.     IF_ERROR(status, "ATA Manager Inquiry failed\n")
  289.  
  290.     printf("ATA Manager inquiry:\n");
  291.     PrintNumVersion("\tATA Manager Version:", pb.ataMgrVersion);
  292.     printf("\tBusses:\t\t%d\n\tDevices:\t%d\n",
  293.                 pb.ataBusCnt, pb.ataDevCnt);
  294.     printf("\tPIO Modes:\t%x\n\tDMA Modes:\t%d\n\tMulti DMA Modes:%x\n",
  295.                  pb.ataPioModes, pb.ataSingleDMAModes, pb.ataMultiDMAModes);
  296.     printf("-----------------------------------------\n\n");    
  297.     return (status);
  298. }
  299.  
  300.  
  301. // ---------------------------------------------------------------------------
  302. OSErr         ScanATABusses (void)
  303. // ---------------------------------------------------------------------------
  304. //
  305. //  Display information about the ATA Busses
  306. //
  307. {
  308.     ataDrvrRegister        pb;
  309.     OSErr                status;
  310.  
  311. // Get first device ID (yes you have to do this once)
  312.     CLEAR(pb);
  313.     pb.ataPBFunctionCode     =    kATAMgrFindDriverRefnum;
  314.     pb.ataPBVers            =    kATAPBVers1;
  315.     pb.ataPBDeviceID         =     (UInt32)0x0000ffff;
  316.     status                     =     ataManager((ataPB*) &pb );
  317.  
  318. // loop through devices
  319.     for    (pb.ataPBDeviceID = (UInt32) pb.ataDeviceNextID;
  320.          pb.ataPBDeviceID != 0xff;
  321.          pb.ataPBDeviceID = (UInt32) pb.ataDeviceNextID)
  322.         {             
  323.             status = ataManager((ataPB*) &pb );
  324.             IF_ERROR(status, "ATA Find Driver failed\n")
  325.             
  326.             printf("Device %d %#s\n", pb.ataPBDeviceID, DrvrRefToName(pb.ataDrvrRefNum) );
  327.             DisplayATADriveIdentity(pb.ataPBDeviceID);
  328.             
  329.         printf("-----------------------------------------\n\n");    
  330.         };    
  331.     
  332.     printf("\n");    
  333.     return (status);
  334. }
  335.  
  336.  
  337.  
  338. // ---------------------------------------------------------------------------
  339. OSErr         DisplayATADriveIdentity (UInt32 deviceID)
  340. // ---------------------------------------------------------------------------
  341. //
  342. //  Display information about the ATA Identify Info
  343. //
  344. {
  345.     ataIdentify            pb;
  346.     ataDevConfiguration    pb1;
  347.     
  348.     UInt16        buffer[255];
  349.     OSErr        status;
  350.     
  351.  
  352. // Get Driver Configuration
  353.     CLEAR(pb1);
  354.     pb1.ataPBFunctionCode     =    kATAMgrGetDrvConfiguration;
  355.     pb1.ataPBVers            =    kATAPBVers2;
  356.     pb1.ataPBDeviceID         =    deviceID;
  357.     
  358.     status = ataManager((ataPB*) &pb1 );
  359.     IF_ERROR(status, "ATA GetDrvConfiguration failed\n")
  360.  
  361.  
  362. // Setup Identify block;
  363.     CLEAR(pb);
  364.     pb.ataPBFunctionCode     =    kATAMgrDriveIdentify;
  365.     pb.ataPBVers            =    kATAPBVers1;
  366.     pb.ataPBDeviceID        =    deviceID;
  367.      pb.ataPBFlags             =     mATAFlagIORead + mATAFlagByteSwap ;
  368.      
  369.      if(pb1.ataDeviceType == kDevATAPI) pb.ataPBFlags += mATAFlagProtocol1;
  370.      
  371.     pb.ataPBTimeOut            =    100;
  372.     pb.ataPBBuffer            =    (void*) buffer;
  373.     
  374.     status = ataManager((ataPB*) &pb );
  375.     IF_ERROR(status, "ATA DriveIdentify failed\n")
  376.  
  377.     printf("Configuration: (");
  378.  
  379.     switch(pb1.ataDeviceType){
  380.         case kDevUnknown:    
  381.                         printf("Unknown protocol"); 
  382.                         break;
  383.         
  384.         case kDevATA:
  385.                         printf("ATA"); 
  386.                         break;
  387.                              
  388.         case kDevATAPI:    
  389.                         printf("ATAPI"); 
  390.                         break;
  391.                         
  392.         case kDevPCMCIA:    
  393.                         printf("PCMCIA"); 
  394.                         break;
  395.     }
  396.     
  397.     switch(pb1.ataSocketType){
  398.         case kSocketUnknown:    
  399.                         printf(", Unknown Socket"); 
  400.                         break;
  401.         
  402.         case kSocketInternal:
  403.                         printf(", Internal"); 
  404.                         break;
  405.                              
  406.         case kSocketMediaBay:    
  407.                         printf(", Media Bay"); 
  408.                         break;
  409.                         
  410.         case kkSocketPCMCIA:    
  411.                         printf(", PCMCIA, Vcc=%d, Vpp1=%d, Vpp2=%d", 
  412.                                         pb1.atapcVcc, pb1.atapcVpp1,pb1.atapcVpp2); 
  413.                         break;
  414.     }
  415.  
  416.     printf(")\n");
  417.  
  418.     DumpFormatedBuffer(buffer, kIdentFormat);
  419. };
  420.  
  421.  
  422.  
  423.  
  424. // ---------------------------------------------------------------------------
  425. Boolean     ATAManagerPresent    (void)
  426. // ---------------------------------------------------------------------------
  427. //
  428. // returns true if this machine has the ata manager
  429. //
  430. {
  431.         return (TrapAvailable(kATATrap));
  432. }
  433.  
  434. // ---------------------------------------------------------------------------
  435. Boolean     ATAHardwarePresent        (void)
  436. // ---------------------------------------------------------------------------
  437. //
  438. // returns true if this machine has ata hardware
  439. //
  440. {
  441.     UInt16    configFlags;
  442.  
  443.     // Hardware configuration flags
  444.     configFlags = LMGetHWCfgFlags();
  445.     
  446.     return (configFlags & 0x0080);
  447. }
  448.  
  449. //------------------------------------------------------------------------------------
  450. #pragma mark -
  451.  
  452. #define NumToolboxTraps() (                                \
  453.         (NGetTrapAddress(_InitGraf, ToolTrap)            \
  454.                 == NGetTrapAddress(0xAA6E, ToolTrap))    \
  455.             ? 0x200 : 0x400                                \
  456.     )
  457. #define GetTrapType(theTrap) (                            \
  458.         (((theTrap) & 0x800) != 0) ? ToolTrap : OSTrap    \
  459.     )
  460.  
  461. // ---------------------------------------------------------------------------
  462. Boolean     TrapAvailable        (short theTrap)
  463. // ---------------------------------------------------------------------------
  464. // (see Inside Mac VI 3-8)
  465. {
  466.         TrapType                trapType;
  467.         
  468.         trapType = GetTrapType(theTrap);
  469.         if (trapType == ToolTrap) {
  470.             theTrap &= 0x07FF;
  471.             if (theTrap >= NumToolboxTraps())
  472.                 theTrap = _Unimplemented;
  473.         }
  474.         return (
  475.             NGetTrapAddress(theTrap, trapType)
  476.             != NGetTrapAddress(_Unimplemented, ToolTrap)
  477.         );
  478. }
  479.  
  480. // ---------------------------------------------------------------------------
  481. void         PrintNumVersion        (char *label, NumVersion version )
  482. // ---------------------------------------------------------------------------
  483. //
  484. //    Decode version number info
  485. //
  486. {
  487.     char            *stage;
  488.  
  489.     switch (version.stage) {
  490.     case developStage:    stage = "d";        break;
  491.     case alphaStage:    stage = "a";        break;
  492.     case betaStage:        stage = "b";        break;
  493.     case finalStage:    stage = "";            break;
  494.     default:            stage = "?";        break;
  495.     
  496.     }
  497.     printf("%s %d.%d.%d",
  498.         label,
  499.         version.majorRev,
  500.         (version.minorAndBugRev>>4), (version.minorAndBugRev & 0xf),
  501.         stage);
  502.     if(version.stage != finalStage) printf(".%d",version.nonRelRev);
  503.     
  504.     printf(" (hex %08lx)\n",    (* ((unsigned long *) &version)));
  505. }
  506.  
  507.  
  508.  
  509. // ---------------------------------------------------------------------------
  510. void        DumpFormatedBuffer    (void* p,  const FormatTablePtr format) 
  511. // ---------------------------------------------------------------------------
  512. //
  513. // Dump formatted buffer
  514. //
  515.  
  516. {    
  517.     unsigned short            *idInfo = p;
  518.          
  519.     register char            *charField;
  520.     register short            fieldLength;
  521.     register short            i;
  522.     register long            value;
  523.     register FormatTablePtr    formatPtr;
  524.     
  525. #define FORMAT    (*formatPtr)
  526.  
  527.     for (formatPtr = format; FORMAT.format != kEndOfTable; formatPtr++) {
  528.             printf("%35s", FORMAT.label);
  529.             switch (FORMAT.format) {
  530.             // Decimal values come as two words with the words swapped.
  531.             case kDecimal:
  532.                 value = 0;
  533.                 for (i = FORMAT.lastWord; i >= FORMAT.firstWord; i--) {
  534.                     value <<= 16;
  535.                     value += idInfo[i];
  536.                 }
  537.                 printf(" %lu", value);    // was %lu
  538.                 break;
  539.             case kHex:
  540.                 for (i = FORMAT.lastWord; i >= FORMAT.firstWord; i--) {
  541.                     value = idInfo[i];
  542.                     printf(" %04ld", value);
  543.                 }
  544.                 break;
  545.             case kLeftJust:
  546.                 charField = (char *) &idInfo[FORMAT.firstWord];
  547.                 fieldLength = (FORMAT.lastWord - FORMAT.firstWord + 1)
  548.                             * sizeof (unsigned short);
  549.                 /*
  550.                  * First scan for an unspecified field.
  551.                  */
  552.                 for (i = 0; i <= fieldLength; i++) {
  553.                     if (charField[i] != '\0')
  554.                         goto gotLeftJustField;
  555.                 }
  556.                 printf(" <not specified>");
  557.                 break;
  558. gotLeftJustField:
  559.                 for (i = fieldLength; i > 0; --i) {
  560.                     if (charField[i - 1] != ' ')
  561.                         break;
  562.                 }
  563.                 printf(" \"%.*s\"", (int) i, charField);
  564.                 break;
  565.             case kRightJust:
  566.                 charField = (char *) &idInfo[FORMAT.firstWord];
  567.                 fieldLength = (FORMAT.lastWord - FORMAT.firstWord + 1)
  568.                             * sizeof (unsigned short);
  569.                 /*
  570.                  * First scan for an unspecified field.
  571.                  */
  572.                 for (i = 0; i <= fieldLength; i++) {
  573.                     if (charField[i] != '\0')
  574.                         goto gotRightJustField;
  575.                 }
  576.                 printf(" <not specified>");
  577.                 break;
  578. gotRightJustField:
  579.                 for (i = 0; i < fieldLength; i++) {
  580.                     if (charField[i] != ' ')
  581.                         break;
  582.                 }
  583.                 printf(" \"%.*s\"", (int) (fieldLength - i), &charField[i]);
  584.                 break;
  585.             }
  586.             printf("\n");
  587.         }
  588. //        DumpRawBuffer( p,512);
  589. }    
  590.     
  591. // ---------------------------------------------------------------------------
  592. void        DumpRawBuffer        ( UInt8 *bufferPtr, int length )
  593. // ---------------------------------------------------------------------------
  594. //
  595. // Dump buffer
  596. //
  597.  
  598. {
  599.         register int            i;
  600.         int                        lineStart;
  601.         int                        lineLength;
  602.         short                    c;
  603.  
  604. #define kLineSize    16
  605.         for (lineStart = 0; lineStart < length; lineStart += lineLength) {
  606.             lineLength = kLineSize;
  607.             if (lineStart + lineLength > length)
  608.                 lineLength = length - lineStart;
  609.             printf("%03x %3d:", lineStart, lineStart);
  610.             for (i = 0; i < lineLength; i++)
  611.                 printf(" %02x", bufferPtr[lineStart + i] & 0xFF);
  612.             for (; i < kLineSize; i++)
  613.                 printf("   ");
  614.             printf("  ");
  615.             for (i = 0; i < lineLength; i++) {
  616.                 c = bufferPtr[lineStart + i] & 0xFF;
  617.                 if (c > ' ' && c < '~')
  618.                     printf("%c", c);
  619.                 else {
  620.                     printf(".");
  621.                 }
  622.             }
  623.             printf("\n");
  624.         }
  625. }
  626.  
  627.  
  628.         
  629. // ---------------------------------------------------------------------------
  630. char*        DrvrRefToName(short refNum)
  631. // ---------------------------------------------------------------------------
  632. //
  633. //  lookup driver name in table
  634. //
  635.  
  636. {
  637.         AuxDCEHandle*        UTable  = (AuxDCEHandle*) LMGetUTableBase();
  638.         DCtlPtr                dctl;
  639.         Ptr                    p;    
  640.         
  641.         if(!refNum) return ((char*) "\p<none>");
  642.  
  643.         dctl = (DCtlPtr) *UTable[~refNum];
  644.         p      =  dctl->dCtlDriver;
  645.         if( dctl->dCtlFlags  & 0x0040) p = (void*) *p;
  646.  
  647.         return  ( p?(char*) (p+18):(char*)"\p-Purged-");
  648. }
  649.